package com.nexus.core.exception;

import com.nexus.core.exception.annotation.ExceptionLevel;

/**
 * 异常基类
 *
 * @Date 2025/7/23 14:21
 * @Author luzhengning
 **/
public class BaseException extends RuntimeException {

    /**
     * 携带的数据信息/业务等数据
     *
     * @Date 2025/7/30 17:25
     * @Author luzhengning
     **/
    private Object data;

    /**
     * 错误码，子类需指定默认值
     *
     * @Date 2025/7/30 17:23
     * @Author luzhengning
     **/
    private int errorCode;

    /**
     * 错误等级，日志记录
     *
     * @Date 2025/7/30 17:24
     * @Author luzhengning
     **/
    private ExceptionLevel level = ExceptionLevel.WARN;

    public BaseException() {
        super();
    }

    public BaseException(int defaultErrorCode) {
        this.errorCode = defaultErrorCode;
    }

    public BaseException(Object message) {
        this.data = message;
    }

    public BaseException(String message, Throwable cause) {
        super(message, cause);
    }

    public BaseException(int defaultErrorCode,String message, Throwable cause) {
        super(message, cause);
        this.errorCode = defaultErrorCode;
    }

    public BaseException(int defaultErrorCode, String message, Object... data) {
        super(message);
        this.errorCode = defaultErrorCode;
        if (data.length > 0) {
            this.data = data[0];
        }
    }

    public <T extends BaseException> T DEBUG() {
        this.level = ExceptionLevel.DEBUG;
        return (T) this;
    }

    public <T extends BaseException> T INFO() {
        this.level = ExceptionLevel.INFO;
        return (T) this;
    }

    public <T extends BaseException> T WARN() {
        this.level = ExceptionLevel.WARN;
        return (T) this;
    }

    public <T extends BaseException> T ERROR() {
        this.level = ExceptionLevel.ERROR;
        return (T) this;
    }

    public <T extends BaseException> T FATAL() {
        this.level = ExceptionLevel.FATAL;
        return (T) this;
    }

    /**
     * 重写toString方法，包含所有属性信息
     *
     * @Date 2025/7/30 17:20
     * @Author luzhengning
     **/
    @Override
    public String toString() {
        return this.getClass().getSimpleName() +
                "[" + "errorCode=" + errorCode + ", " + "level=" + level + ", " + "data=" + (data != null ? data : "null") + ", " + "message=" + (getMessage() != null ? getMessage() : "null") + // 包含父类的message
                "]";
    }

    public int getErrorCode() {
        return this.errorCode;
    }

    public <T extends BaseException> T setErrorCode(int errorCode) {
        this.errorCode = errorCode;
        return (T) this;
    }

    public Object getData() {
        return this.data;
    }

    public <T extends BaseException> T setData(Object data) {
        this.data = data;
        return (T) this;
    }

    public ExceptionLevel getExceptionLevel() {
        return this.level;
    }

    public void setExceptionLevel(ExceptionLevel level) {
        this.level = level;
    }

}